package com.jqp.admin.common.face;

import cn.hutool.json.JSONUtil;
import com.baidu.aip.face.AipFace;
import com.jqp.admin.common.face.constants.BaiduFaceConstants;
import com.jqp.admin.common.face.propreties.BaiduFaceProperties;
import com.jqp.admin.db.service.JdbcService;
import com.jqp.admin.rbac.data.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;

/**
 * @author TangCheng
 * @date 2022/6/16 11:24
 * @description
 */
@Component
@Slf4j
public class FaceUtil {

    private static AipFace client;

    private static JdbcService jdbcService;

    private static BaiduFaceProperties baiduFaceProperties;

    /**
     * 检测图片中是否存在人脸
     * @param imageBase64
     * @return
     */
    public static boolean detectFace(String imageBase64) {

        JSONObject detectResult = client.detect(imageBase64, BaiduFaceConstants.FACE_TYPE_BASE64, null);

        if (detectResult == null || !detectResult.getString("error_msg").equals("SUCCESS")) {
            return false;
        }

        JSONObject result = detectResult.getJSONObject("result");
        int faceNum = result.getInt("face_num");

        if (faceNum < 1) {
            log.error("识别不到人脸");
            return false;
        }

        return true;
    }

    /**
     * 将人员加入人脸库
     *
     * @param userInfo
     * @param repositoryName
     * @param imageBase64
     * @return
     */
    public static boolean addToFaceRepository(User userInfo,
                                              String repositoryName,
                                              String imageBase64) {

        if (StringUtils.isBlank(repositoryName)) {
            repositoryName = BaiduFaceConstants.DEFAULT_FACE_REPOSITORY;
        }

        // 参数设置（示例下表格对参数进行介绍）
        HashMap<String, String> map = new HashMap<>();
        map.put("quality_control", "NORMAL");//图片质量
        map.put("liveness_control", "LOW");//活体检测
        map.put("user_info", JSONUtil.toJsonStr(userInfo));//用户信息

        JSONObject result = client.addUser(imageBase64,
                BaiduFaceConstants.FACE_TYPE_BASE64,
                repositoryName,
                userInfo.getId().toString(),
                map);

        // 解析结果
        if (null == result) {
            return false;
        }

        if (result.getString("error_msg").equals("SUCCESS")) {
            return true;
        } else {
            log.error("添加人脸库失败,用户信息：用户名-{}, 用户id-{}", userInfo.getName(), userInfo.getId());
            return false;
        }
    }

    /**
     * 拿照片比对人脸库，获取用户信息
     *
     * @param imageBase64
     * @param repositoryName
     * @return
     */
    public static User getUserInfoByFace(String imageBase64, String repositoryName) {

        if (StringUtils.isBlank(repositoryName)) {
            repositoryName = BaiduFaceConstants.DEFAULT_FACE_REPOSITORY;
        }

        JSONObject result = client.search(imageBase64,
                BaiduFaceConstants.FACE_TYPE_BASE64,
                repositoryName,
                null);

        if (null == result || !result.getString("error_msg").equals("SUCCESS")) {
            return null;
        }

        JSONObject faceResult = result.getJSONObject("result");
        if (null == faceResult
                || faceResult.getJSONArray("user_list") == null
                || faceResult.getJSONArray("user_list").length() == 0) {
            log.error("没有匹配的人脸信息！");
            return null;
        }

        // 取出比中的人
        JSONObject person = (JSONObject) faceResult.getJSONArray("user_list").get(0);
        int score = person.getInt("score");

        // 比较分值，符合阈值才继续
        if (score < baiduFaceProperties.getScore()) {
            log.error("匹配的人脸不满足分数阈值！");
            return null;
        }

        Long userId = Long.valueOf(person.getString("user_id"));

        return jdbcService.getById(User.class, userId);
    }


    @Autowired
    public void setClient(AipFace client) {
        FaceUtil.client = client;
    }

    @Resource
    public void setJdbcService(JdbcService jdbcService) {
        FaceUtil.jdbcService = jdbcService;
    }

    @Autowired
    public void setBaiduFaceProperties(BaiduFaceProperties baiduFaceProperties) {
        FaceUtil.baiduFaceProperties = baiduFaceProperties;
    }
}
